/**
 * Candidate number: 35834
 */
package tv.starfu.systems;

import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.EntityProcessingSystem;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import tv.starfu.components.FutureTransform;
import tv.starfu.components.RainbowWarrior;
import tv.starfu.components.Transform;

/**
 * Takes input data (keys/joystick) and stores it in the FutureTransform
 * @author nia radical
 */
public class InputSystem extends EntityProcessingSystem {

    private InputManager inputManager;
    private Vector3f inputVelocity;
    
    //TODO implement quaternion rotator on camera
    private Quaternion inputRotation;
    private float yaw = 0f;
    private float roll = 0f;
    private float pitch = 0f;
    private float[] angles = new float[3];
    
    // Setting movement speed
    public float speed = 0.4f;
    public float pitchAmount = FastMath.QUARTER_PI * 0.25f;
    
    private ComponentMapper<FutureTransform>    controlMapper;
    private ComponentMapper<RainbowWarrior>     playerMapper;
    private ComponentMapper<Transform>          transformMapper;
  
    public InputSystem(InputManager im) {
        super(FutureTransform.class, RainbowWarrior.class);
        inputManager = im;
    }
    
    @Override
    public void initialize() {
        controlMapper   = new ComponentMapper<FutureTransform>(FutureTransform.class, world);
        transformMapper = new ComponentMapper<Transform>(Transform.class, world);
        playerMapper    = new ComponentMapper<RainbowWarrior>(RainbowWarrior.class, world);
        
        inputVelocity = new Vector3f(0,0,0);
        inputRotation = new Quaternion();   
        keyBinding();
    }
    
    
    @Override
    protected void process(Entity e) {
        FutureTransform controller = controlMapper.get(e);
        RainbowWarrior player = playerMapper.get(e);
        Transform transform = transformMapper.get(e);
        
        // Convert input angles to radians
        angles[0] = yaw; 
        angles[2] = roll*FastMath.DEG_TO_RAD; 
        angles[1] = pitch;

        // Copy input data to FutureTransform
        controller.position.z = inputVelocity.z;
        controller.position.x = inputVelocity.x;
        controller.position.y = inputVelocity.y;
        
       // inputRotation = inputRotation.fromAngleNormalAxis(pitch, Vector3f.UNIT_Y.normalize());
      //  controller.position = inputRotation.mult(controller.position);
    //    transform.direction = controller.position;
}
    
      /**
     * Define listener actions
     */  
      private AnalogListener analogListener = new AnalogListener() {
        public void onAnalog(String name,float value,float tpf) {
            if(name.equals("PitchUp"))   { inputVelocity.y += speed; } 
            if(name.equals("PitchDown")) { inputVelocity.y -= speed; }
            if(name.equals("Forward"))   { inputVelocity.z += speed; } 
            if(name.equals("Reverse"))   { inputVelocity.z -= speed; } 
            if(name.equals("Left"))      { inputVelocity.x += speed; } 
            if(name.equals("Right"))     { inputVelocity.x -= speed; } 
            
        }
    };
      
      private ActionListener actionListener = new ActionListener() {
          public void onAction(String name, boolean keyPressed,float tpf) {
              if(name.equals("Jump") && !keyPressed)    {  System.out.println("Jump!");   }
              if(name.equals("Shoot") && !keyPressed)   {  System.out.println("Shoot!");  }
          }
      };
    

      /**
       * Define input mappings
       */
    public void keyBinding() {
        inputManager.addMapping("Forward",  new KeyTrigger(KeyInput.KEY_UP));
        inputManager.addMapping("Reverse",  new KeyTrigger(KeyInput.KEY_DOWN));
        inputManager.addMapping("Left",     new KeyTrigger(KeyInput.KEY_J), new KeyTrigger(KeyInput.KEY_LEFT));
        inputManager.addMapping("Right",    new KeyTrigger(KeyInput.KEY_L), new KeyTrigger(KeyInput.KEY_RIGHT));
        inputManager.addMapping("PitchUp",   new KeyTrigger(KeyInput.KEY_I), new KeyTrigger(KeyInput.KEY_Q));
        inputManager.addMapping("PitchDown", new KeyTrigger(KeyInput.KEY_K), new KeyTrigger(KeyInput.KEY_W));
        
        inputManager.addMapping("Jump",     new KeyTrigger(KeyInput.KEY_A), new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        inputManager.addMapping("Shoot",    new KeyTrigger(KeyInput.KEY_S));
        
        inputManager.addListener(actionListener, new String[]{ "Jump", "Shoot" });
        inputManager.addListener(analogListener, new String[]{ "Forward", "Reverse", "Left", "Right", 
                                                                "PitchUp", "PitchDown"});
            }
    }
